package org.javaboy.sms_login.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpSession;
import org.javaboy.sms_login.config.RabbitConfig;
import org.javaboy.sms_login.model.SendSmsLog;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.security.SecureRandom;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SendSmsService {
    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    SendSmsLogService sendSmsLogService;
    SecureRandom secureRandom = new SecureRandom();

    public void sendSms(String phone, HttpSession session) throws JsonProcessingException {
        int code = secureRandom.nextInt(9000) + 1000;
        session.setAttribute(phone, code);
        //将要发送的内容发送到 MQ，将来有一个专门的短信服务来消费 MQ 的消息
        //消息内容
        Map<String, String> content = new HashMap<>();
        content.put("phone", phone);
        content.put("content", "【登录验证码】：您的登录验证码是：" + code + "，请勿泄露");
        //将要发送的内容存入到数据库
        SendSmsLog sendSmsLog = new SendSmsLog();
        String msgContent = new ObjectMapper().writeValueAsString(content);
        sendSmsLog.setContent(msgContent);
        //重试次数，默认为 0
        sendSmsLog.setCount(0);
        sendSmsLog.setExchange(RabbitConfig.SEND_SMS_EXCHANGE);
        sendSmsLog.setCreateTime(new Date());
        //0 表示发送中
        sendSmsLog.setStatus(0);
        sendSmsLog.setRoutingKey(RabbitConfig.SEND_SMS_QUEUE);
        //30s 之后重试
        sendSmsLog.setTryTime(new Date(System.currentTimeMillis() + 30000));
        sendSmsLogService.save(sendSmsLog);
        //发送消息
        rabbitTemplate.convertAndSend("RabbitConfig.SEND_SMS_EXCHANGE", RabbitConfig.SEND_SMS_QUEUE, msgContent, new CorrelationData(sendSmsLog.getMsgId().toString()));
    }


    @Scheduled(cron = "0/10 * * * * ?")
    public void reSend() {
        //查询状态为 0，并且重试时间小于当前时间的消息
        List<SendSmsLog> list = sendSmsLogService.getSmsLog(0, new Date());
        for (SendSmsLog log : list) {
            if (log.getStatus() == 3) {
                //说明已经达到重试的上限了，消息发送失败
                sendSmsLogService.updateStatus(log.getMsgId().toString(), 2);
            } else {
                //数据库中消息重试次数 + 1
                sendSmsLogService.updateCount(log.getMsgId(), log.getCount() + 1);
                //重新发送
                rabbitTemplate.convertAndSend(log.getExchange(), log.getRoutingKey(), log.getContent(), new CorrelationData(log.getMsgId().toString()));
            }
        }
    }
}
